Skip to content

feat: support OpenAPI 3.2 additional operations#10956

Open
cmmoran wants to merge 5 commits into
swagger-api:masterfrom
cmmoran:oas32-pr
Open

feat: support OpenAPI 3.2 additional operations#10956
cmmoran wants to merge 5 commits into
swagger-api:masterfrom
cmmoran:oas32-pr

Conversation

@cmmoran

@cmmoran cmmoran commented Jul 13, 2026

Copy link
Copy Markdown

Description

Adds OpenAPI 3.2 Path Item additionalOperations support to Swagger UI. Custom operation methods are discovered and rendered as first-class operations, including their request parameters, request bodies, responses, deep links, validation state, and operation-specific metadata.

Custom methods retain the exact method token from the OpenAPI document. Standard methods continue to use the existing built-in behavior, while custom methods receive neutral styling rather than being added as hard-coded method names.

Motivation and Context

OpenAPI 3.2 allows arbitrary operation method names under additionalOperations. Swagger UI previously omitted those operations from the operation list and could not resolve their operation data through the normal selector paths.

This PR depends on the corresponding Swagger Client support in swagger-api/swagger-js#4238. Swagger UI should consume a released Swagger Client version containing that change; this PR intentionally does not add a dependency on a fork, branch, or immutable development tag.

How Has This Been Tested?

  • npm run lint-errors
  • npm run test:unit -- --runInBand test/unit/core/plugins/oas32/query-operation-rendering.test.js test/unit/core/plugins/oas32/spec-extensions/wrap-selectors.test.js test/unit/core/plugins/spec/selectors.js
  • Targeted tests passed: 61 tests across 3 suites.
  • Full unit suite: 842 passed, 12 skipped, 3 suites skipped.

Types of changes

  • No code changes (src/ is unmodified: changes to documentation, CI, metadata, etc.)
  • Dependency changes (any modification to dependencies in package.json)
  • Bug fixes (non-breaking change which fixes an issue)
  • Improvements (misc. changes to existing features)
  • Features (non-breaking change which adds functionality)

My changes...

  • are breaking changes to a public API (config options, System API, major UI change, etc.).
  • are breaking changes to a private API (Redux, component props, utility functions, etc.).
  • are breaking changes to a developer API (npm script behavior changes, new dev system dependencies, etc.).
  • are not breaking changes.

Documentation

  • My changes do not require a change to the project documentation.
  • My changes require a change to the project documentation.
  • If yes to above: I have updated the documentation accordingly.

Automated tests

  • My changes can not or do not need to be tested.
  • My changes can and should be tested by unit and/or integration tests.
  • If yes to above: I have added tests to cover my changes.
  • If yes to above: I have taken care to cover edge cases in my tests.
  • All new and relevant existing tests passed.

@cmmoran cmmoran marked this pull request as ready for review July 15, 2026 17:54

@wbizmo wbizmo left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Went through this properly, cloned it and actually ran the tests instead of just reading the diff.

Ran the exact test command from the description: 60/60 pass, confirmed it myself. Also ran the full unit suite to check for regressions elsewhere, 841/853 pass, the rest are pre existing skips unrelated to this. Lint is clean too.

Quick heads up on the "14 files changed" count, a couple of those (package lock, CI workflow files) are just leftovers from a master merge, not actually part of this feature.

Two things I'd want to understand better before this merges, not blockers:

  1. getOAS3RequiredRequestBodyContentType and isMediaTypeSchemaPropertiesEqual now read from specJsonWithResolvedSubtrees(state) instead of the raw resolvedSubtrees branch. That changes behavior for regular standard method operations too, not just the new additionalOperations stuff. Tests still pass so it seems fine, but the checklist says "not breaking changes" and this quietly changes the data source for existing code paths. Was that intentional?

  2. This depends on an unreleased swagger js PR (#4238) for full support, which is handled the right way (no fork/branch pin). But all the new tests mock the state directly, there's nothing testing this against the actual released swagger-client resolver. Might be worth confirming it behaves once that release is out.

Otherwise this is solid work, good test coverage on the new logic and nothing broke anywhere else.

@cmmoran

cmmoran commented Jul 16, 2026

Copy link
Copy Markdown
Author
  1. getOAS3RequiredRequestBodyContentType and isMediaTypeSchemaPropertiesEqual now read from specJsonWithResolvedSubtrees(state) instead of the raw resolvedSubtrees branch. That changes behavior for regular standard method operations too, not just the new additionalOperations stuff. Tests still pass so it seems fine, but the checklist says "not breaking changes" and this quietly changes the data source for existing code paths. Was that intentional?
  2. This depends on an unreleased swagger js PR swagger-api/swagger-js#4238 for full support, which is handled the right way (no fork/branch pin). But all the new tests mock the state directly, there's nothing testing this against the actual released swagger-client resolver. Might be worth confirming it behaves once that release is out.

Otherwise this is solid work, good test coverage on the new logic and nothing broke anywhere else.

Thanks for checking this carefully.

  1. Good catch. The change to use specJsonWithResolvedSubtrees was intentional so the same selector path can support both standard operations and additionalOperations. Standard operations are still expected to use the resolved subtree as the authoritative source. I’ve added an explicit regression test covering that precedence so the intended behavior is documented and protected.

  2. Agreed. Swagger UI should not pin to the fork or an unreleased branch. Swagger JS swagger-api/swagger-js#4238 is the prerequisite implementation. Once it is released, Swagger UI should update its normal swagger-client dependency/lockfile to that released version and add a focused integration check against it. The current UI tests intentionally mock selector state because the currently released Swagger Client does not yet support OAS 3.2 additionalOperations.

@wbizmo wbizmo left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the quick turnaround on this, and for actually engaging with both points instead of just closing them out.

The new test on resolved subtree precedence is exactly what I was hoping to see, it sets json and resolvedSubtrees to different values on purpose and asserts the resolved subtree wins for a standard operation. That documents the intended behavior and protects it going forward. Ran the full suite locally, 854 tests, all passing, no regressions.

On the swagger-js dependency, that's a reasonable sequencing plan. Makes sense to land this now with mocked tests and follow up with a real integration check once swagger-client ships OAS 3.2 support.

Approving.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants